package souralven.jcomicreader.controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import souralven.jcomicreader.model.FileFormat;
import souralven.jcomicreader.ui.ReaderFrame;
import souralven.jcomicreader.util.FileUtil;
import souralven.jcomicreader.util.ImageUtil;

public class ComicController {

    public static final double MIN_ZOOM_LEVEL = 0.25;
    public static final double MAX_ZOOM_LEVEL = 2;

    private int imageNumber;
	private int imageCount;
	private ReaderFrame frame;
	private BufferedImage currentImage;
	private double currentScale;
	private File comicFile;
	private FileFormat format;

	public ComicController(final ReaderFrame frame) {
		this.imageNumber = 0;
		this.frame = frame;
		this.currentImage = null;
		this.currentScale = 1;
		this.comicFile = null;
	}

	public void showComic(final File comicFile) throws IOException {
		this.comicFile = comicFile;
		this.format = FileUtil.obtainComicFormat(comicFile);
		this.imageCount = format.getFileReader().count(comicFile);
		showImage();
	}

	public void zoomIn(final double percentage) {
		zoom(currentScale + percentage);
	}

	public void zoomOut(final double percentage) {
		zoom(currentScale - percentage);
	}

	public void adjustWindowSizeToImage() {
		int width = currentImage.getWidth();
		int height = currentImage.getHeight();
		frame.getContentPane().setSize(width, height);
		frame.pack();
	}

	public void adjustZoomToWindow() {
		int width = frame.getScrollPane().getWidth();
		int height = frame.getScrollPane().getHeight();
		double scale = ImageUtil.getScaleFactor(width, height, currentImage);
		zoom(scale);
	}

	public void goNext() throws IOException {
		imageNumber ++;
		updateOnChangeImage();
	}

	public void goBack() throws IOException {
		imageNumber --;
		updateOnChangeImage();
	}

	private void zoom(final double scale) {
	    if (scale > 0) {
	        currentScale = scale;
	        BufferedImage image = ImageUtil.scale(currentScale, currentImage);
	        frame.getImageLabel().setIcon(image);
	    }
	    frame.updateUI(imageNumber, imageCount, currentScale);
	}

    private void updateOnChangeImage() throws IOException {
        BufferedImage image = getImageToDisplay();
        frame.getImageLabel().setIcon(image);
        frame.updateUI(imageNumber, imageCount, currentScale);
    }

    private void showImage() throws IOException {
		BufferedImage image = getImageToDisplay();
		frame.getImageLabel().setIcon(image);
		frame.updateToolBarUI(imageNumber, imageCount, currentScale);
	}

    private BufferedImage getImageToDisplay() throws IOException {
        final InputStream inputStream = format.getFileReader().read(comicFile, imageNumber);
        currentImage = ImageIO.read(inputStream);
        return ImageUtil.scale(currentScale, currentImage);
    }
}
